home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / comm / term / term34Source.lha / termEmulation.c < prev    next >
C/C++ Source or Header  |  1993-07-16  |  45KB  |  2,620 lines

  1. /*
  2. **    termEmulation.c
  3. **
  4. **    Terminal emulation (parsing and processing) routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* One of the emulation callback routines. */
  13.  
  14. typedef VOID (* __regargs EPTR)(STRPTR Buffer);
  15.  
  16.     /* This structure describes an ANSI control sequence. */
  17.  
  18. struct ControlCode
  19. {
  20.     UBYTE    FirstChar;
  21.     STRPTR    Match;
  22.     UBYTE    LastChar;
  23.  
  24.     BYTE    ExactSize;
  25.     EPTR    Func;
  26. };
  27.  
  28.     /* How many characters we will keep in the scan buffer. */
  29.  
  30. #define MAX_SCAN_SIZE    256
  31.  
  32.     /* Flag indicating whether the cursor has already been
  33.      * erased or not.
  34.      */
  35.  
  36. STATIC BYTE        CursorEnabled = FALSE;
  37.  
  38.     /* Cursor handling data. */
  39.  
  40. STATIC WORD        LastCursorX = -1,
  41.             LastCursorY = -1;
  42.  
  43. STATIC LONG        DestX,
  44.             DestY,
  45.             XSize;
  46.  
  47. STATIC BYTE        CursorGhosted = FALSE;
  48.  
  49.     /* Backup style. */
  50.  
  51. STATIC UBYTE        StyleType = FS_NORMAL;
  52.  
  53.     /* Cursor backup data. */
  54.  
  55. STATIC struct CursorData CursorBackup;
  56.  
  57.     /* A couple of internally referenced variables. */
  58.  
  59. STATIC BYTE    CharsInBuffer    = 0,
  60.         ScanStep    = 0;
  61. STATIC UBYTE    SaveBuffer[MAX_SCAN_SIZE + 1];
  62.  
  63.     /* Character access tables. */
  64.  
  65. STATIC UBYTE Table0[256] =
  66. {
  67.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  68.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  69.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  70.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  71.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  72.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  73.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  74.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  75.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  76.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  77.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  78.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  79.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  80.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  81.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  82.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  83. };
  84.  
  85. STATIC UBYTE Table1[256] =
  86. {
  87.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  88.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  89.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  90.     1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
  91.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  92.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  93.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  94.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  95.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  96.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  97.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  98.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  99.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  100.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  101.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  102.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  103. };
  104.  
  105. STATIC UBYTE Table2[256] =
  106. {
  107.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  108.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  109.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  110.     1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,
  111.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  112.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  113.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  114.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  115.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  116.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  117.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  118.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  119.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  120.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  121.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  122.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  123. };
  124.  
  125. STATIC UBYTE Table3[256] =
  126. {
  127.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  128.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  129.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  130.     1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,
  131.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  132.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  133.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  134.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  135.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  136.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  137.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  138.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  139.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  140.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  141.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  142.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  143. };
  144.  
  145. STATIC UBYTE Table4[256] =
  146. {
  147.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  148.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  149.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  150.     1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,
  151.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  152.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  153.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  154.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  155.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  156.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  157.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  158.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  159.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  160.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  161.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  162.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  163. };
  164.  
  165.     /* This follows the control code information. */
  166.  
  167. struct ControlCode ANSICode[] =
  168. {
  169.     /* Single Character Sequences. */
  170.  
  171.     'D',    Table0,     0 ,    1,    (EPTR)CursorScrollDown,
  172.     'M',    Table0,     0 ,    1,    (EPTR)CursorScrollUp,
  173.     'E',    Table0,     0 ,    1,    (EPTR)NextLine,
  174.     '7',    Table0,     0 ,    1,    (EPTR)SaveCursor,
  175.     '8',    Table0,     0 ,    1,    (EPTR)LoadCursor,
  176.     '=',    Table0,     0 ,    1,    (EPTR)NumericAppMode,
  177.     '>',    Table0,     0 ,    1,    (EPTR)NumericAppMode,
  178.     'N',    Table0,     0 ,    1,    (EPTR)Ignore,
  179.     'O',    Table0,     0 ,    1,    (EPTR)Ignore,
  180.     'H',    Table0,     0 ,    1,    (EPTR)SetTab,
  181.     'Z',    Table0,     0 ,    1,    (EPTR)RequestTerminal,
  182.     'c',    Table0,     0 ,    1,    (EPTR)Reset,
  183.     '<',    Table0,     0 ,    1,    (EPTR)Ignore,
  184.     '~',    Table0,     0 ,    1,    (EPTR)Ignore,
  185.     'n',    Table0,     0 ,    1,    (EPTR)Ignore,
  186.     '}',    Table0,     0 ,    1,    (EPTR)Ignore,
  187.     'o',    Table0,     0 ,    1,    (EPTR)Ignore,
  188.     '|',    Table0,     0 ,    1,    (EPTR)Ignore,
  189.  
  190.     /* Double Character Sequences. */
  191.  
  192.     '[',    Table0,    's',    2,    (EPTR)SaveCursor,
  193.     '[',    Table0,    'u',    2,    (EPTR)LoadCursor,
  194.     '(',    Table0,    'A',    2,    (EPTR)FontStuff,
  195.     '(',    Table0,    'B',    2,    (EPTR)FontStuff,
  196.     '(',    Table0,    '0',    2,    (EPTR)FontStuff,
  197.     ')',    Table0,    'A',    2,    (EPTR)FontStuff,
  198.     ')',    Table0,    'B',    2,    (EPTR)FontStuff,
  199.     ')',    Table0,    '0',    2,    (EPTR)FontStuff,
  200.     '#',    Table0,    '3',    2,    (EPTR)ScaleFont,
  201.     '#',    Table0,    '4',    2,    (EPTR)ScaleFont,
  202.     '#',    Table0,    '5',    2,    (EPTR)ScaleFont,
  203.     '#',    Table0,    '6',    2,    (EPTR)ScaleFont,
  204.     '#',    Table0,    '8',    2,    (EPTR)AlignmentTest,
  205.     ' ',    Table0,    'F',    2,    (EPTR)Ignore,
  206.     ' ',    Table0,    'G',    2,    (EPTR)Ignore,
  207.  
  208.     /* Multiple Character Sequence. */
  209.  
  210.     '[',    Table3,    'i',    0,    (EPTR)PrinterController,
  211.  
  212.     '[',    Table3,    'n',    0,    (EPTR)RequestInformation,
  213.     '[',    Table3,    'c',    0,    (EPTR)RequestTerminal,
  214.     '[',    Table3,    'h',    0,    (EPTR)SetSomething,
  215.     '[',    Table3,    'l',    0,    (EPTR)SetSomething,
  216.  
  217.     '[',    Table4,    'h',    0,    (EPTR)Ignore,
  218.  
  219.     '[',    Table1,    'A',    0,    (EPTR)MoveCursor,
  220.     '[',    Table1,    'B',    0,    (EPTR)MoveCursor,
  221.     '[',    Table1,    'C',    0,    (EPTR)MoveCursor,
  222.     '[',    Table1,    'D',    0,    (EPTR)MoveCursor,
  223.     '[',    Table1,    'K',    0,    (EPTR)EraseLine,
  224.     '[',    Table1,    'J',    0,    (EPTR)EraseScreen,
  225.     '[',    Table1,    'P',    0,    (EPTR)EraseCharacters,
  226.     '[',    Table1,    '@',    0,    (EPTR)InsertCharacters,
  227.     '[',    Table1,    'L',    0,    (EPTR)InsertLine,
  228.     '[',    Table1,    'M',    0,    (EPTR)ClearLine,
  229.     '[',    Table1,    'g',    0,    (EPTR)SetTabs,
  230.     '[',    Table1,    'q',    0,    (EPTR)Ignore,
  231.  
  232.     '[',    Table2,    'H',    0,    (EPTR)SetAbsolutePosition,
  233.     '[',    Table2,    'f',    0,    (EPTR)SetAbsolutePosition,
  234.     '[',    Table2,    'm',    0,    (EPTR)SetAttributes,
  235.     '[',    Table2,    'y',    0,    (EPTR)Ignore,
  236.     '[',    Table2,    'r',    0,    (EPTR)SetRegion,
  237.  
  238.     '[',    Table1,    'S',    0,    (EPTR)ScrollUp,
  239.     '[',    Table1,    'T',    0,    (EPTR)ScrollDown
  240. };
  241.  
  242. STATIC WORD NumCodes = sizeof(ANSICode) / sizeof(struct ControlCode);
  243.  
  244.     /* GetFontWidth():
  245.      *
  246.      *    Get the font width of the current line.
  247.      */
  248.  
  249. STATIC WORD
  250. GetFontWidth(VOID)
  251. {
  252.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  253.     {
  254.         if(Config -> EmulationConfig -> FontScale == SCALE_HALF)
  255.             return((WORD)(TextFontWidth / 2));
  256.         else
  257.             return(TextFontWidth);
  258.     }
  259.     else
  260.     {
  261.         if(Config -> EmulationConfig -> FontScale == SCALE_HALF)
  262.             return(TextFontWidth);
  263.         else
  264.             return((WORD)(TextFontWidth * 2));
  265.     }
  266. }
  267.  
  268.     /* ColourValue(UWORD Colour):
  269.      *
  270.      *    Calculate the value of a given colour (brightness).
  271.      */
  272.  
  273. STATIC WORD __inline
  274. ColourValue(UWORD Colour)
  275. {
  276.     BYTE    Red,Green,Blue;
  277.     WORD    Sum;
  278.  
  279.     Red    =  Colour >> 8;
  280.     Green    = (Colour >> 4) & 0xF;
  281.     Blue    =  Colour       & 0xF;
  282.  
  283.     Sum = (Red + Green + Blue) / 3;
  284.  
  285.     return(Sum);
  286. }
  287.  
  288.     /* ScrollRegion(WORD Direction):
  289.      *
  290.      *    Scroll the current scroll region up or down.
  291.      */
  292.  
  293. STATIC VOID __regargs
  294. ScrollRegion(WORD Direction)
  295. {
  296.     WORD RegionTop,RegionBottom,RegionLines;
  297.     LONG Dir,MinY,MaxY;
  298.  
  299.     if(Direction < 0)
  300.         Dir = -Direction;
  301.     else
  302.         Dir = Direction;
  303.  
  304.     if(RegionSet)
  305.     {
  306.         MinY         = MUL_Y(Top);
  307.         MaxY        = MUL_Y(Bottom + 1) - 1;
  308.  
  309.         RegionTop    = Top;
  310.         RegionBottom    = Bottom + 1;
  311.         RegionLines    = Bottom - Top + 1;
  312.     }
  313.     else
  314.     {
  315.         MinY        = 0;
  316.         MaxY         = MUL_Y(LastLine + 1) - 1;
  317.  
  318.         RegionTop    = 0;
  319.         RegionBottom    = LastLine + 1;
  320.         RegionLines    = LastLine + 1;
  321.     }
  322.  
  323.     BackupRender();
  324.  
  325.     RasterScrollRegion(Direction,RegionTop,RegionBottom,RegionLines);
  326.  
  327.     if(Config -> EmulationConfig -> ScrollMode == SCROLL_JUMP || (TextFontHeight & 1))
  328.     {
  329.         if(Dir > RegionLines)
  330.             ScrollLineRectFill(RPort,0,MinY,LastPixel,MaxY);
  331.         else
  332.         {
  333.             if(Direction > 0)
  334.                 ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,FALSE);
  335.             else
  336.                 ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,FALSE);
  337.         }
  338.     }
  339.     else
  340.     {
  341.         if(Direction > 0)
  342.             ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,TRUE);
  343.         else
  344.             ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,TRUE);
  345.     }
  346.  
  347.     BackupRender();
  348. }
  349.  
  350.     /* LastChar(STRPTR Buffer):
  351.      *
  352.      *    Return the last character in a string.
  353.      */
  354.  
  355. STATIC UBYTE __inline
  356. LastChar(STRPTR Buffer)
  357. {
  358.     WORD Offset = 0;
  359.  
  360.     while(Buffer[Offset])
  361.         Offset++;
  362.  
  363.     return(Buffer[Offset - 1]);
  364. }
  365.  
  366.     /* ReadValue(STRPTR Buffer,BYTE *Value):
  367.      *
  368.      *    Parse a buffer for numbers and return a pointer
  369.      *    to the next buffer element to contain additional
  370.      *    information.
  371.      */
  372.  
  373. STATIC STRPTR __inline
  374. ReadValue(STRPTR Buffer,WORD *Value)
  375. {
  376.     while(*Buffer && *Buffer != ';' && (*Buffer < '0' || *Buffer > '9'))
  377.         Buffer++;
  378.  
  379.     if(*Buffer)
  380.     {
  381.         *Value = 0;
  382.  
  383.         while(*Buffer >= '0' && *Buffer <= '9')
  384.             *Value = (*Value * 10) + (*Buffer++ - '0');
  385.     }
  386.     else
  387.         *Value = -1;
  388.  
  389.     if(*Buffer == ';' || *Buffer == ' ')
  390.         return(Buffer + 1);
  391.     else
  392.         return(NULL);
  393. }
  394.  
  395.     /* DoCancel():
  396.      *
  397.      *    Cancel any currently scanned sequence.
  398.      */
  399.  
  400. BYTE __regargs
  401. DoCancel()
  402. {
  403.     InSequence    = FALSE;
  404.     CharsInBuffer    = ScanStep = 0;
  405.  
  406.     return(FALSE);
  407. }
  408.  
  409.     /* CSIFake():
  410.      *
  411.      *    This routine was added to support 8-bit control
  412.      *    sequences introduced by a CSI character.
  413.      */
  414.  
  415. VOID
  416. CSIFake()
  417. {
  418.         /* Reset scanner */
  419.  
  420.     DoCancel();
  421.  
  422.         /* Perform as if ESC [ had been transmitted. */
  423.  
  424.     InSequence = ParseCode('[');
  425. }
  426.  
  427.     /* ParseCode(UBYTE c):
  428.      *
  429.      *    Input:    A character to be passed through the ANSI code
  430.      *        parser.
  431.      *
  432.      *    Output:    FALSE if input characters did form a valid ANSI
  433.      *        control sequence or if input characters did not
  434.      *        form an ANSI control sequence at all.
  435.      *
  436.      *        TRUE if input characters did possibly introduce
  437.      *        a valid ANSI control sequence.
  438.      */
  439.  
  440. BYTE __regargs
  441. ParseCode(UBYTE c)
  442. {
  443.         /* ScanStep = 0:    This is the first character
  444.          *            to introduce a control sequence.
  445.          */
  446.  
  447.     if(!ScanStep)
  448.     {
  449.         register WORD i;
  450.  
  451.             /* Scan all available codes and try to find
  452.              * a match.
  453.              */
  454.  
  455.         for(i = 0 ; i < NumCodes ; i++)
  456.         {
  457.                 /* This character may introduce a
  458.                  * control sequence.
  459.                  */
  460.  
  461.             if(ANSICode[i] . FirstChar == c)
  462.             {
  463.                     /* If this is a single
  464.                      * character control sequence
  465.                      * call the approriate function
  466.                      * and exit immediately.
  467.                      */
  468.  
  469.                 if(ANSICode[i] . ExactSize == 1)
  470.                 {
  471.                     if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  472.                     {
  473.                         SaveBuffer[CharsInBuffer++] = c;
  474.                         SaveBuffer[CharsInBuffer  ] = 0;
  475.  
  476.                         (*ANSICode[i] . Func)(SaveBuffer);
  477.                     }
  478.  
  479.                     CharsInBuffer = ScanStep = 0;
  480.  
  481.                     return(FALSE);
  482.                 }
  483.                 else
  484.                 {
  485.                         /* The length of this control
  486.                          * sequence is greater than
  487.                          * a single character. Save
  488.                          * the input character and
  489.                          * return.
  490.                          */
  491.  
  492.                     ScanStep = i;
  493.  
  494.                     SaveBuffer[CharsInBuffer++] = c;
  495.  
  496.                     return(TRUE);
  497.                 }
  498.             }
  499.         }
  500.     }
  501.     else
  502.     {
  503.         if(CharsInBuffer < MAX_SCAN_SIZE)
  504.         {
  505.             register WORD i;
  506.  
  507.                 /* Scan the remaining codes for a match. */
  508.  
  509.             for(i = ScanStep ; i < NumCodes ; i++)
  510.             {
  511.                     /* This sequence begins with the
  512.                      * same character the parser was
  513.                      * initialized with, so let's take
  514.                      * a look at it.
  515.                      */
  516.  
  517.                 if(ANSICode[i] . FirstChar == SaveBuffer[0])
  518.                 {
  519.                         /* This character is supposed to
  520.                          * terminate the sequence, so exit.
  521.                          */
  522.  
  523.                     if(ANSICode[i] . LastChar == c)
  524.                     {
  525.                         if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  526.                         {
  527.                             SaveBuffer[CharsInBuffer++] = c;
  528.                             SaveBuffer[CharsInBuffer  ] = 0;
  529.  
  530.                             (*ANSICode[i] . Func)(SaveBuffer);
  531.                         }
  532.  
  533.                         CharsInBuffer = ScanStep = 0;
  534.  
  535.                         return(FALSE);
  536.                     }
  537.                     else
  538.                     {
  539.                             /* If this character is part of
  540.                              * a legal sequence store it
  541.                              * and return.
  542.                              */
  543.  
  544.                         if(ANSICode[i] . Match[c])
  545.                         {
  546.                             ScanStep = i;
  547.  
  548.                             SaveBuffer[CharsInBuffer++] = c;
  549.  
  550.                             return(TRUE);
  551.                         }
  552.                     }
  553.                 }
  554.             }
  555.         }
  556.     }
  557.  
  558.         /* Return failure. */
  559.  
  560.     CharsInBuffer = ScanStep = 0;
  561.  
  562.     return(FALSE);
  563. }
  564.  
  565.     /* ToggleCursor():
  566.      *
  567.      *    (Re)draw the cursor image.
  568.      */
  569.  
  570. VOID
  571. ToggleCursor()
  572. {
  573.     if(Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL)
  574.     {
  575.         UWORD    OldAPen    = ReadAPen(RPort),
  576.             OldBPen    = ReadBPen(RPort),
  577.             OldDrMd    = ReadDrMd(RPort),
  578.  
  579.             Left    = WindowLeft + DestX,
  580.             Top    = WindowTop + DestY;
  581.  
  582.         if(Kick30)
  583.         {
  584.             SetABPenDrMd(RPort,DepthMask,OldBPen,JAM1 | COMPLEMENT);
  585.  
  586.             if(UseMasking)
  587.             {
  588.                 UBYTE Mask = RPort -> Mask;
  589.  
  590.                 SetWrMsk(RPort,DepthMask);
  591.  
  592.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  593.  
  594.                 SetWrMsk(RPort,Mask);
  595.             }
  596.             else
  597.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  598.  
  599.             SetABPenDrMd(RPort,OldAPen,OldBPen,OldDrMd);
  600.         }
  601.         else
  602.         {
  603.             SetAPen(RPort,DepthMask);
  604.             SetDrMd(RPort,JAM1 | COMPLEMENT);
  605.  
  606.             if(UseMasking)
  607.             {
  608.                 UBYTE Mask = RPort -> Mask;
  609.  
  610.                 SetWrMsk(RPort,DepthMask);
  611.  
  612.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  613.  
  614.                 SetWrMsk(RPort,Mask);
  615.             }
  616.             else
  617.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  618.  
  619.             SetAPen(RPort,OldAPen);
  620.             SetDrMd(RPort,OldDrMd);
  621.         }
  622.     }
  623. }
  624.  
  625.     /* NormalCursor():
  626.      *
  627.      *    Enable normal (filled) cursor image.
  628.      */
  629.  
  630. VOID
  631. NormalCursor()
  632. {
  633.     if(CursorGhosted)
  634.     {
  635.         if(CursorEnabled)
  636.         {
  637.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  638.  
  639.             ToggleCursor();
  640.  
  641.             SetAfPt(RPort,NULL,0);
  642.  
  643.             ToggleCursor();
  644.         }
  645.  
  646.         CursorGhosted = FALSE;
  647.     }
  648. }
  649.  
  650.     /* GhostCursor():
  651.      *
  652.      *    Enable ghosted (checkered) cursor image.
  653.      */
  654.  
  655. VOID
  656. GhostCursor()
  657. {
  658.     if(!CursorGhosted)
  659.     {
  660.         if(CursorEnabled)
  661.         {
  662.             ToggleCursor();
  663.  
  664.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  665.  
  666.             ToggleCursor();
  667.  
  668.             SetAfPt(RPort,NULL,0);
  669.         }
  670.  
  671.         CursorGhosted = TRUE;
  672.     }
  673. }
  674.  
  675.     /* ClipBlitCursor(UBYTE DoClip,UBYTE DoMove):
  676.      *
  677.      *    Change the appearance of the cursor.
  678.      */
  679.  
  680. VOID __regargs
  681. ClipBlitCursor(UBYTE DoClip,UBYTE DoMove)
  682. {
  683.     if(DoClip || DoMove)
  684.     {
  685.         if(CursorY != LastCursorY || CursorX != LastCursorX)
  686.         {
  687.             STATIC LONG X,Y,Column;
  688.  
  689.             if(CursorY != LastCursorY)
  690.             {
  691.                 if(CursorY > LastLine)
  692.                     Y = LastLine;
  693.                 else
  694.                 {
  695.                     if(CursorY < 0)
  696.                         Y = 0;
  697.                     else
  698.                         Y = CursorY;
  699.                 }
  700.  
  701.                 if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  702.                     Column = LastColumn;
  703.                 else
  704.                     Column = ((LastColumn + 1) / 2) - 1;
  705.  
  706.                 DestY = MUL_Y(Y);
  707.  
  708.                 LastCursorY = CursorY;
  709.             }
  710.  
  711.             LastCursorX = CursorX;
  712.  
  713.             if(CursorX > Column)
  714.                 X = Column;
  715.             else
  716.             {
  717.                 if(CursorX < 0)
  718.                     X = 0;
  719.                 else
  720.                     X = CursorX;
  721.             }
  722.  
  723.             if(Config -> EmulationConfig -> FontScale == SCALE_NORMAL)
  724.             {
  725.                 if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  726.                 {
  727.                     DestX = MUL_X(X);
  728.                     XSize = TextFontWidth;
  729.                 }
  730.                 else
  731.                 {
  732.                     DestX = MUL_X(X) * 2;
  733.                     XSize = TextFontWidth * 2;
  734.  
  735.                     if(X > ((LastColumn + 1) / 2) - 1)
  736.                         X = ((LastColumn + 1) / 2) - 1;
  737.                 }
  738.             }
  739.             else
  740.             {
  741.                 if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  742.                 {
  743.                     DestX = MUL_X(X) / 2;
  744.                     XSize = TextFontWidth / 2;
  745.                 }
  746.                 else
  747.                 {
  748.                     DestX = MUL_X(X);
  749.                     XSize = TextFontWidth;
  750.  
  751.                     if(X > ((LastColumn + 1) / 2) - 1)
  752.                         X = ((LastColumn + 1) / 2) - 1;
  753.                 }
  754.             }
  755.         }
  756.  
  757.         if(DoMove)
  758.             Move(RPort,WindowLeft + DestX,WindowTop + DestY + TextFontBase);
  759.  
  760.         if(DoClip)
  761.         {
  762.             if(CursorGhosted)
  763.             {
  764.                 SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  765.  
  766.                 ToggleCursor();
  767.  
  768.                 SetAfPt(RPort,NULL,0);
  769.             }
  770.             else
  771.                 ToggleCursor();
  772.         }
  773.     }
  774. }
  775.  
  776.     /* ClearCursor():
  777.      *
  778.      *    Clear the cursor image.
  779.      */
  780.  
  781. VOID
  782. ClearCursor()
  783. {
  784.     if(CursorEnabled)
  785.     {
  786.         ClipBlitCursor(TRUE,FALSE);
  787.  
  788.         CursorEnabled = FALSE;
  789.     }
  790. }
  791.  
  792.     /* DrawCursor():
  793.      *
  794.      *    Explicitely (re-)draw the cursor image.
  795.      */
  796.  
  797. VOID
  798. DrawCursor()
  799. {
  800.     if(!CursorEnabled)
  801.     {
  802.         ClipBlitCursor(TRUE,FALSE);
  803.  
  804.         CursorEnabled = TRUE;
  805.     }
  806. }
  807.  
  808.     /* BackupRender():
  809.      *
  810.      *    Save current draw modes, pen and position or restore
  811.      *    the data.
  812.      */
  813.  
  814. VOID
  815. BackupRender()
  816. {
  817.     STATIC BYTE    Called = FALSE;
  818.     STATIC UBYTE    DrMd,
  819.             FgPen,
  820.             BgPen;
  821.     STATIC UWORD    OldX,OldY;
  822.     STATIC UBYTE    Style;
  823.  
  824.     if(!Called)
  825.     {
  826.         DrMd    = ReadDrMd(RPort);
  827.         FgPen    = ReadAPen(RPort);
  828.         BgPen    = ReadBPen(RPort);
  829.  
  830.         OldX    = RPort -> cp_x - WindowLeft;
  831.         OldY    = RPort -> cp_y - WindowTop;
  832.  
  833.         Style    = StyleType;
  834.  
  835.         Called    = TRUE;
  836.     }
  837.     else
  838.     {
  839.         if(ReadDrMd(RPort) != DrMd)
  840.             SetDrMd(RPort,DrMd);
  841.  
  842.         if(ReadAPen(RPort) != FgPen)
  843.             SetAPen(RPort,FgPen);
  844.  
  845.         if(ReadBPen(RPort) != BgPen)
  846.             SetBPen(RPort,BgPen);
  847.  
  848.         Move(RPort,OldX + WindowLeft,OldY + WindowTop);
  849.  
  850.         if(Style != StyleType)
  851.         {
  852.             SetSoftStyle(RPort,Style,0xFF);
  853.  
  854.             StyleType = Style;
  855.         }
  856.  
  857.         Called = FALSE;
  858.     }
  859. }
  860.  
  861.     /* ShiftChar(LONG Size):
  862.      *
  863.      *    Simulate character insertion at the current cursor
  864.      *    position by shifting the whole line Size times eight pixels
  865.      *    to the right.
  866.      */
  867.  
  868. VOID __regargs
  869. ShiftChar(LONG Size)
  870. {
  871.     LONG DeltaX,MinX,MinY;
  872.  
  873.     MinY = MUL_Y(CursorY);
  874.  
  875.     if(Config -> EmulationConfig -> FontScale == SCALE_NORMAL)
  876.     {
  877.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  878.         {
  879.             DeltaX    = MUL_X(Size);
  880.             MinX    = MUL_X(CursorX);
  881.         }
  882.         else
  883.         {
  884.             DeltaX    = MUL_X(Size) * 2;
  885.             MinX    = MUL_X(CursorX) * 2;
  886.         }
  887.     }
  888.     else
  889.     {
  890.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  891.         {
  892.             DeltaX    = MUL_X(Size) / 2;
  893.             MinX    = MUL_X(CursorX) / 2;
  894.         }
  895.         else
  896.         {
  897.             DeltaX    = MUL_X(Size);
  898.             MinX    = MUL_X(CursorX);
  899.         }
  900.     }
  901.  
  902.     if(MinX < WindowWidth)
  903.     {
  904.         BackupRender();
  905.  
  906.         ScrollLineRaster(RPort,-DeltaX,0,MinX,MinY,LastPixel,MinY + TextFontHeight - 1,FALSE);
  907.  
  908.         BackupRender();
  909.     }
  910. }
  911.  
  912.     /* Ignore():
  913.      *
  914.      *    Do nothing, return immediately.
  915.      */
  916.  
  917. VOID
  918. Ignore()
  919. {
  920. }
  921.  
  922.     /* ScrollDown(STRPTR Buffer):
  923.      *
  924.      *    Scroll the current region down.
  925.      */
  926.  
  927. VOID __regargs
  928. ScrollDown(STRPTR Buffer)
  929. {
  930.     WORD Value;
  931.  
  932.     ReadValue(Buffer,&Value);
  933.  
  934.     if(Value < 1)
  935.         Value = 1;
  936.  
  937.     ScrollRegion(-Value);
  938. }
  939.  
  940.     /* ScrollUp(STRPTR Buffer):
  941.      *
  942.      *    Scroll the current region up.
  943.      */
  944.  
  945. VOID __regargs
  946. ScrollUp(STRPTR Buffer)
  947. {
  948.     WORD Value;
  949.  
  950.     ReadValue(Buffer,&Value);
  951.  
  952.     if(Value < 1)
  953.         Value = 1;
  954.  
  955.     ScrollRegion(Value);
  956. }
  957.  
  958.     /* CursorScrollDown():
  959.      *
  960.      *    Move cursor down and scroll region if necessary.
  961.      */
  962.  
  963. VOID
  964. CursorScrollDown()
  965. {
  966.     DownLine();
  967.  
  968.     ClipBlitCursor(FALSE,TRUE);
  969. }
  970.  
  971. VOID
  972. DownLine()
  973. {
  974.     UBYTE InRegion = TRUE;
  975.     WORD  Hit      = LastLine;
  976.  
  977.     if(RegionSet)
  978.     {
  979.         if(CursorY <= Bottom)
  980.             Hit = Bottom;
  981.         else
  982.             InRegion = FALSE;
  983.     }
  984.  
  985.     if(CursorY == Hit)
  986.     {
  987.         if(InRegion)
  988.             ScrollRegion(1);
  989.     }
  990.     else
  991.     {
  992.         CursorY++;
  993.  
  994.         if(CursorY > LastLine)
  995.             CursorY = LastLine;
  996.  
  997.         ConFontScaleUpdate();
  998.     }
  999. }
  1000.  
  1001.     /* CursorScrollUp():
  1002.      *
  1003.      *    Move cursor up and scroll region if necessary.
  1004.      */
  1005.  
  1006. VOID
  1007. CursorScrollUp()
  1008. {
  1009.     BYTE InRegion    = TRUE;
  1010.     WORD Hit    = 0;
  1011.  
  1012.     if(RegionSet)
  1013.     {
  1014.         if(CursorY >= Top)
  1015.             Hit = Top;
  1016.         else
  1017.             InRegion = FALSE;
  1018.     }
  1019.  
  1020.     if(CursorY == Hit)
  1021.     {
  1022.         if(InRegion)
  1023.             ScrollRegion(-1);
  1024.     }
  1025.     else
  1026.     {
  1027.         if(--CursorY < 0)
  1028.             CursorY = 0;
  1029.  
  1030.         ConFontScaleUpdate();
  1031.     }
  1032.  
  1033.     ClipBlitCursor(FALSE,TRUE);
  1034. }
  1035.  
  1036.     /* NextLine():
  1037.      *
  1038.      *    Do something like CR+LF.
  1039.      */
  1040.  
  1041. VOID
  1042. NextLine()
  1043. {
  1044.     CursorX = 0;
  1045.  
  1046.     DownLine();
  1047.  
  1048.     ClipBlitCursor(FALSE,TRUE);
  1049. }
  1050.  
  1051.     /* SaveCursor():
  1052.      *
  1053.      *    Save cursor position and rendering attributes.
  1054.      */
  1055.  
  1056. VOID
  1057. SaveCursor()
  1058. {
  1059.     CursorBackup . Charset        = Charset;
  1060.     CursorBackup . Attributes    = Attributes;
  1061.     CursorBackup . CursorX        = CursorX;
  1062.     CursorBackup . CursorY        = CursorY;
  1063.     CursorBackup . Style        = StyleType;
  1064.     CursorBackup . FgPen        = GetPenIndex(ReadAPen(RPort));
  1065.     CursorBackup . BgPen        = GetPenIndex(ReadBPen(RPort));
  1066.     CursorBackup . CurrentFont    = CurrentFont;
  1067.     CursorBackup . CharMode[0]    = CharMode[0];
  1068.     CursorBackup . CharMode[1]    = CharMode[1];
  1069. }
  1070.  
  1071.     /* FontStuff(STRPTR Buffer):
  1072.      *
  1073.      *    Set the drawing font (standard characters/line).
  1074.      */
  1075.  
  1076. VOID __regargs
  1077. FontStuff(STRPTR Buffer)
  1078. {
  1079.     BYTE Changed = FALSE;
  1080.  
  1081.     if(Buffer[0] == '(')
  1082.     {
  1083.         switch(LastChar(Buffer))
  1084.         {
  1085.             case 'A':
  1086.             case 'B':
  1087.  
  1088.                 if(CharMode[0] != TABLE_ASCII && !Charset)
  1089.                     Changed = TRUE;
  1090.  
  1091.                 CharMode[0] = TABLE_ASCII;
  1092.  
  1093.                 break;
  1094.  
  1095.             case '0':
  1096.  
  1097.                 if(CharMode[0] != TABLE_GFX && !Charset)
  1098.                     Changed = TRUE;
  1099.  
  1100.                 CharMode[0] = TABLE_GFX;
  1101.  
  1102.                 break;
  1103.         }
  1104.     }
  1105.  
  1106.     if(Buffer[0] == ')')
  1107.     {
  1108.         switch(LastChar(Buffer))
  1109.         {
  1110.             case 'A':
  1111.             case 'B':
  1112.  
  1113.                 if(CharMode[1] != TABLE_ASCII && Charset == 1)
  1114.                     Changed = TRUE;
  1115.  
  1116.                 CharMode[1] = TABLE_ASCII;
  1117.  
  1118.                 break;
  1119.  
  1120.             case '0':
  1121.  
  1122.                 if(CharMode[1] != TABLE_GFX && Charset == 1)
  1123.                     Changed = TRUE;
  1124.  
  1125.                 CharMode[1] = TABLE_GFX;
  1126.  
  1127.                 break;
  1128.         }
  1129.     }
  1130.  
  1131.     if(Changed)
  1132.     {
  1133.         BackupRender();
  1134.  
  1135.         if(Charset)
  1136.             DoShiftIn();
  1137.         else
  1138.             DoShiftOut();
  1139.  
  1140.         BackupRender();
  1141.     }
  1142. }
  1143.  
  1144.     /* LoadCursor():
  1145.      *
  1146.      *    Load cursor position and rendering attributes.
  1147.      */
  1148.  
  1149. VOID
  1150. LoadCursor()
  1151. {
  1152.     Charset        = CursorBackup . Charset;
  1153.  
  1154.     CharMode[0]    = CursorBackup . CharMode[0];
  1155.     CharMode[1]    = CursorBackup . CharMode[1];
  1156.  
  1157.     if(CurrentFont != CursorBackup . CurrentFont)
  1158.     {
  1159.         CurrentFont = CursorBackup . CurrentFont;
  1160.  
  1161.         SetFont(RPort,CurrentFont);
  1162.  
  1163.         ConOutputUpdate();
  1164.     }
  1165.  
  1166.     if(StyleType != CursorBackup . Style)
  1167.     {
  1168.         SetSoftStyle(RPort,CursorBackup . Style,0xFF);
  1169.  
  1170.         StyleType = CursorBackup . Style;
  1171.     }
  1172.  
  1173.     if(ReadAPen(RPort) != MappedPens[0][CursorBackup . FgPen])
  1174.         SetAPen(RPort,MappedPens[0][CursorBackup . FgPen]);
  1175.  
  1176.     if(ReadBPen(RPort) != MappedPens[0][CursorBackup . BgPen])
  1177.         SetBPen(RPort,MappedPens[0][CursorBackup . BgPen]);
  1178.  
  1179.     Attributes    = CursorBackup . Attributes;
  1180.     CursorX        = CursorBackup . CursorX;
  1181.     CursorY        = CursorBackup . CursorY;
  1182.  
  1183.     ConFontScaleUpdate();
  1184.  
  1185.     ClipBlitCursor(FALSE,TRUE);
  1186. }
  1187.  
  1188.     /* ScaleFont(STRPTR Buffer):
  1189.      *
  1190.      *    Select a new font scale.
  1191.      */
  1192.  
  1193. VOID __regargs
  1194. ScaleFont(STRPTR Buffer)
  1195. {
  1196.     WORD NewScale,Scale;
  1197.  
  1198.     Scale = RasterAttr[CursorY];
  1199.  
  1200.     NewScale = Scale;
  1201.  
  1202.     switch(LastChar(Buffer))
  1203.     {
  1204.         case '3':
  1205.  
  1206.             NewScale = SCALE_ATTR_TOP2X;
  1207.  
  1208.             break;
  1209.  
  1210.         case '4':
  1211.  
  1212.             NewScale = SCALE_ATTR_BOT2X;
  1213.  
  1214.             break;
  1215.  
  1216.         case '5':
  1217.  
  1218.             NewScale = SCALE_NORMAL;
  1219.  
  1220.             break;
  1221.  
  1222.         case '6':
  1223.  
  1224.             NewScale = SCALE_ATTR_2X;
  1225.  
  1226.             break;
  1227.     }
  1228.  
  1229.     if(Scale != NewScale)
  1230.     {
  1231.         UBYTE    *RasterPtr    = &Raster[CursorY * RasterWidth];
  1232.         WORD     RightMargin    = LastColumn + 1,
  1233.              CursorXSave    = CursorX;
  1234.  
  1235.         if(NewScale != SCALE_ATTR_NORMAL)
  1236.             RightMargin /= 2;
  1237.  
  1238.         RasterAttr[CursorY] = NewScale;
  1239.  
  1240.         ConFontScaleUpdate();
  1241.  
  1242.         if(((Config -> EmulationConfig -> FontScale == SCALE_NORMAL) && (NewScale == SCALE_ATTR_NORMAL)) || ((Config -> EmulationConfig -> FontScale == SCALE_HALF) && (NewScale == SCALE_ATTR_2X)))
  1243.         {
  1244.             Move(RPort,WindowLeft,WindowTop + MUL_Y(CursorY) + TextFontBase);
  1245.             Text(RPort,RasterPtr,RightMargin);
  1246.         }
  1247.         else
  1248.         {
  1249.             CursorX = 0;
  1250.  
  1251.             PrintScaled(RasterPtr,RightMargin,NewScale);
  1252.         }
  1253.  
  1254.         if(CursorXSave >= RightMargin)
  1255.             CursorX = RightMargin - 1;
  1256.         else
  1257.             CursorX = CursorXSave;
  1258.     }
  1259.  
  1260.     ClipBlitCursor(FALSE,TRUE);
  1261. }
  1262.  
  1263.     /* AlignmentTest():
  1264.      *
  1265.      *    Perform screen alignment test, fill the screen with `E's.
  1266.      */
  1267.  
  1268. VOID
  1269. AlignmentTest()
  1270. {
  1271.     STRPTR Buffer;
  1272.  
  1273.     if(Buffer = AllocVec(LastColumn + 1,MEMF_ANY))
  1274.     {
  1275.         WORD i;
  1276.  
  1277.         memset(Buffer,'E',LastColumn + 1);
  1278.  
  1279.         EraseScreen("2");
  1280.  
  1281.         if(Config -> EmulationConfig -> FontScale == SCALE_HALF)
  1282.         {
  1283.             for(i = 0 ; i <= LastLine ; i++)
  1284.             {
  1285.                 CursorX = 0;
  1286.                 CursorY = i;
  1287.  
  1288.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  1289.  
  1290.                 RasterPutString(Buffer,LastColumn + 1);
  1291.                 ScrollLinePutString(LastColumn + 1);
  1292.  
  1293.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1294.                 PrintScaled(Buffer,LastColumn + 1,SCALE_ATTR_NORMAL);
  1295.             }
  1296.         }
  1297.         else
  1298.         {
  1299.             for(i = 0 ; i <= LastLine ; i++)
  1300.             {
  1301.                 CursorX = 0;
  1302.                 CursorY = i;
  1303.  
  1304.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  1305.  
  1306.                 RasterPutString(Buffer,LastColumn + 1);
  1307.                 ScrollLinePutString(LastColumn + 1);
  1308.  
  1309.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1310.                 Text(RPort,Buffer,LastColumn + 1);
  1311.             }
  1312.         }
  1313.  
  1314.         CursorX = CursorY = 0;
  1315.  
  1316.         ClipBlitCursor(FALSE,TRUE);
  1317.  
  1318.         FreeVec(Buffer);
  1319.  
  1320.         ConFontScaleUpdate();
  1321.     }
  1322. }
  1323.  
  1324.     /* SetTab():
  1325.      *
  1326.      *    Set a tabulator stop at the current position.
  1327.      */
  1328.  
  1329. VOID
  1330. SetTab()
  1331. {
  1332.     if(CursorX < TabStopMax)
  1333.         TabStops[CursorX] = TRUE;
  1334. }
  1335.  
  1336.     /* RequestTerminal(STRPTR Buffer):
  1337.      *
  1338.      *    Return the current terminal position.
  1339.      */
  1340.  
  1341. VOID __regargs
  1342. RequestTerminal(STRPTR Buffer)
  1343. {
  1344.     switch(Buffer[0])
  1345.     {
  1346.             /* Make ourselves known as a VT200
  1347.              * terminal.
  1348.              */
  1349.  
  1350.         case '[':
  1351.  
  1352.             if(Buffer[1] != '>')
  1353.                 SerWrite("\033[?62;1;2;6;7;8;9c",-1);
  1354.             else
  1355.                 SerWrite("\033[>1;10;0c",-1);
  1356.  
  1357.             break;
  1358.  
  1359.             /* This is an old status request type,
  1360.              * we will return the standard `I am a
  1361.              * VT101' sequence.
  1362.              */
  1363.  
  1364.         case 'Z':
  1365.  
  1366.             SerWrite("\033[?1;0c",-1);
  1367.             break;
  1368.     }
  1369. }
  1370.  
  1371.     /* SoftReset():
  1372.      *
  1373.      *    Plain and simple: reset the text rendering colours, style and the
  1374.      *    font being used. This works similar to the Reset() call which
  1375.      *    also clears the screen.
  1376.      */
  1377.  
  1378. VOID
  1379. SoftReset()
  1380. {
  1381.         /* Are we running on an external emulation? */
  1382.  
  1383.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  1384.     {
  1385.         XEmulatorResetTextStyles(XEM_IO);
  1386.         XEmulatorResetCharset(XEM_IO);
  1387.     }
  1388.     else
  1389.     {
  1390.             /* Reset the text rendering styles. */
  1391.  
  1392.         SetAttributes("0m");
  1393.  
  1394.         Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  1395.  
  1396.         ConFontScaleUpdate();
  1397.  
  1398.             /* Reset the text rendering colours. */
  1399.  
  1400.         FgPen = GetPenIndex(SafeTextPen);
  1401.         BgPen = 0;
  1402.  
  1403.         if(ReadAPen(RPort) != MappedPens[0][FgPen])
  1404.             SetAPen(RPort,MappedPens[0][FgPen]);
  1405.  
  1406.         if(ReadBPen(RPort) != MappedPens[0][BgPen])
  1407.             SetBPen(RPort,MappedPens[0][BgPen]);
  1408.  
  1409.         SetWrMsk(RPort,DepthMask);
  1410.  
  1411.         CurrentFont = TextFont;
  1412.  
  1413.         SetFont(RPort,CurrentFont);
  1414.  
  1415.         ConOutputUpdate();
  1416.     }
  1417. }
  1418.  
  1419.     /* Reset():
  1420.      *
  1421.      *    Reset terminal to initial state.
  1422.      */
  1423.  
  1424. VOID
  1425. Reset()
  1426. {
  1427.     LONG    MaxColumns,MaxLines,
  1428.         Columns,Lines,
  1429.         i;
  1430.  
  1431.     CursorEnabled = FALSE;
  1432.  
  1433.     if(Window -> Flags & WFLG_WINDOWACTIVE)
  1434.         CursorGhosted = FALSE;
  1435.     else
  1436.         CursorGhosted = TRUE;
  1437.  
  1438.         /* Determine window inner dimensions and top/left edge offsets. */
  1439.  
  1440.     WindowLeft    = Window -> BorderLeft;
  1441.     WindowTop    = Window -> BorderTop;
  1442.  
  1443.     WindowWidth    = Window -> Width - (Window -> BorderLeft + Window -> BorderRight);
  1444.     WindowHeight    = Window -> Height - (Window -> BorderTop + Window -> BorderBottom);
  1445.  
  1446.     MaxColumns    = WindowWidth / TextFontWidth;
  1447.     MaxLines    = WindowHeight / TextFontHeight;
  1448.  
  1449.         /* Set up the new screen width. */
  1450.  
  1451.     if(Config -> TerminalConfig -> NumColumns < 20)
  1452.         Columns = MaxColumns;
  1453.     else
  1454.         Columns = Config -> TerminalConfig -> NumColumns;
  1455.  
  1456.         /* Set up the new screen height. */
  1457.  
  1458.     if(Config -> TerminalConfig -> NumLines < 20)
  1459.         Lines = MaxLines;
  1460.     else
  1461.         Lines = Config -> TerminalConfig -> NumLines;
  1462.  
  1463.         /* More columns than we will be able to display? */
  1464.  
  1465.     if(Columns > MaxColumns)
  1466.         Columns = MaxColumns;
  1467.  
  1468.         /* More lines than we will be able to display? */
  1469.  
  1470.     if(Lines > MaxLines)
  1471.         Lines = MaxLines;
  1472.  
  1473.         /* Set up the central data. */
  1474.  
  1475.     LastColumn    = Columns - 1;
  1476.     LastLine    = Lines - 1;
  1477.     LastPixel    = MUL_X(Columns) - 1;
  1478.  
  1479.     memset(TabStops,FALSE,TabStopMax);
  1480.  
  1481.     for(i = 8 ; i < TabStopMax ; i += 8)
  1482.         TabStops[i] = TRUE;
  1483.  
  1484.     CharMode[0] = TABLE_ASCII;
  1485.     CharMode[1] = TABLE_GFX;
  1486.  
  1487.     Charset = 0;
  1488.  
  1489.     SetAPen(RPort,MappedPens[0][0]);
  1490.  
  1491.     SetWrMsk(RPort,DepthMask);
  1492.  
  1493.     RectFill(RPort,WindowLeft,WindowTop,WindowLeft + WindowWidth - 1,WindowTop + WindowHeight - 1);
  1494.  
  1495.     ScrollLineEraseScreen(2);
  1496.  
  1497.     RasterEraseScreen(2);
  1498.  
  1499.     FgPen = GetPenIndex(SafeTextPen);
  1500.     BgPen = 0;
  1501.  
  1502.     if(ReadAPen(RPort) != MappedPens[0][FgPen])
  1503.         SetAPen(RPort,MappedPens[0][FgPen]);
  1504.  
  1505.     if(ReadBPen(RPort) != MappedPens[0][BgPen])
  1506.         SetBPen(RPort,MappedPens[0][BgPen]);
  1507.  
  1508.     if(StyleType != FS_NORMAL)
  1509.     {
  1510.         SetSoftStyle(RPort,FS_NORMAL,0xFF);
  1511.  
  1512.         StyleType = FS_NORMAL;
  1513.     }
  1514.  
  1515.     CurrentFont = TextFont;
  1516.  
  1517.     SetFont(RPort,CurrentFont);
  1518.  
  1519.     ConOutputUpdate();
  1520.  
  1521.     UseRegion = FALSE;
  1522.     RegionSet = FALSE;
  1523.  
  1524.     Config -> EmulationConfig -> CursorMode        = KEYMODE_STANDARD;
  1525.     Config -> EmulationConfig -> NumericMode    = KEYMODE_STANDARD;
  1526.  
  1527.     Config -> EmulationConfig -> NewLineMode    = FALSE;
  1528.     Config -> EmulationConfig -> InsertMode        = FALSE;
  1529.  
  1530.     Config -> EmulationConfig -> LineWrap        = TRUE;
  1531.     Config -> EmulationConfig -> CursorWrap        = FALSE;
  1532.  
  1533.     Config -> EmulationConfig -> FontScale        = SCALE_NORMAL;
  1534.     Config -> EmulationConfig -> ScrollMode        = SCROLL_JUMP;
  1535.  
  1536.     Attributes    = 0;
  1537.     Top        = 0;
  1538.     Bottom        = LastLine;
  1539.     CursorX        = 0;
  1540.     CursorY        = 0;
  1541.  
  1542.     CursorBackup . Charset        = Charset;
  1543.     CursorBackup . Attributes    = Attributes;
  1544.     CursorBackup . CursorX        = CursorX;
  1545.     CursorBackup . CursorY        = CursorY;
  1546.     CursorBackup . Style        = StyleType;
  1547.     CursorBackup . FgPen        = FgPen;
  1548.     CursorBackup . BgPen        = BgPen;
  1549.     CursorBackup . CurrentFont    = CurrentFont;
  1550.     CursorBackup . CharMode[0]    = CharMode[0];
  1551.     CursorBackup . CharMode[1]    = CharMode[1];
  1552.  
  1553.     ConFontScaleUpdate();
  1554.  
  1555.     ClipBlitCursor(FALSE,TRUE);
  1556. }
  1557.  
  1558.     /* PrinterController(STRPTR Buffer):
  1559.      *
  1560.      *    Controls various screen dump and capture functions.
  1561.      */
  1562.  
  1563. VOID __regargs
  1564. PrinterController(STRPTR Buffer)
  1565. {
  1566.     if(Config -> EmulationConfig -> PrinterEnabled)
  1567.     {
  1568.         switch(Buffer[1])
  1569.         {
  1570.             case 'i':
  1571.             case '0':
  1572.  
  1573.                 if(RegionSet)
  1574.                     PrintRegion(Top,Bottom + 1);
  1575.                 else
  1576.                     PrintRegion(0,LastLine + 1);
  1577.  
  1578.                 break;
  1579.  
  1580.             case '5':
  1581.  
  1582.                 OpenPrinterCapture(TRUE);
  1583.                 break;
  1584.  
  1585.             case '4':
  1586.  
  1587.                 ClosePrinterCapture(FALSE);
  1588.                 break;
  1589.         }
  1590.     }
  1591. }
  1592.  
  1593.     /* RequestInformation(STRPTR Buffer):
  1594.      *
  1595.      *    Request miscellaneous information (state & cursor position).
  1596.      */
  1597.  
  1598. VOID __regargs
  1599. RequestInformation(STRPTR Buffer)
  1600. {
  1601.     UBYTE    LocalBuffer[40];
  1602.     WORD    Value;
  1603.  
  1604.     ReadValue(Buffer,&Value);
  1605.  
  1606.     switch(Value)
  1607.     {
  1608.             /* Terminal status report, return code
  1609.              * for `no malfunction'.
  1610.              */
  1611.  
  1612.         case 5:
  1613.  
  1614.             SerWrite("\033[0n",-1);
  1615.             break;
  1616.  
  1617.             /* The origin is placed at 0/0 and the first
  1618.              * cursor position is 1/1. We'll have to add
  1619.              * 1 to our internal positions since our
  1620.              * universe has been shifted one field to the
  1621.              * left top corner.
  1622.              */
  1623.  
  1624.         case 6:
  1625.  
  1626.             SPrintf(LocalBuffer,"\033[%ld;%ldR",CursorY + 1,CursorX + 1);
  1627.  
  1628.             SerWrite(LocalBuffer,-1);
  1629.  
  1630.             break;
  1631.  
  1632.             /* A VT200 command: request printer status.
  1633.              * We will return `the printer is ready' in
  1634.              * case the printer control commands are
  1635.              * enabled, else return `no printer connected'.
  1636.              */
  1637.  
  1638.         case 15:
  1639.  
  1640.             if(Config -> EmulationConfig -> PrinterEnabled)
  1641.                 SerWrite("\033[?10n",-1);
  1642.             else
  1643.                 SerWrite("\033[?11n",-1);
  1644.  
  1645.             break;
  1646.  
  1647.             /* VT200 command: request user defined
  1648.              * key status. We will return `user
  1649.              * defined keys are locked'.
  1650.              */
  1651.  
  1652.         case 25:
  1653.  
  1654.             SerWrite("\033[?21n",-1);
  1655.             break;
  1656.  
  1657.             /* Another VT200 command: request
  1658.              * keyboard language. We will return
  1659.              * `keyboard language unknown'.
  1660.              */
  1661.  
  1662.         case 26:
  1663.  
  1664.             SerWrite("\033[?27;0n",-1);
  1665.             break;
  1666.     }
  1667. }
  1668.  
  1669.     /* SetSomething(STRPTR Buffer):
  1670.      *
  1671.      *    Set a terminal option.
  1672.      */
  1673.  
  1674. VOID __regargs
  1675. SetSomething(STRPTR Buffer)
  1676. {
  1677.     switch(Buffer[1])
  1678.     {
  1679.         case '?':
  1680.  
  1681.             switch(Buffer[2])
  1682.             {
  1683.                     /* Set cursor keys applications mode. */
  1684.  
  1685.                 case '1':
  1686.  
  1687.                     if(Buffer[3] == 'h')
  1688.                         Config -> EmulationConfig -> CursorMode = KEYMODE_APPLICATION;
  1689.                     else
  1690.                         Config -> EmulationConfig -> CursorMode = KEYMODE_STANDARD;
  1691.  
  1692.                     break;
  1693.  
  1694.                     /* Set line length (132 or 80). */
  1695.  
  1696.                 case '3':
  1697.  
  1698.                     if(Buffer[3] == 'h')
  1699.                     {
  1700.                         if(Config -> EmulationConfig -> FontScale != SCALE_HALF)
  1701.                         {
  1702.                             PrivateConfig = Config;
  1703.  
  1704.                             Config -> EmulationConfig -> FontScale = SCALE_HALF;
  1705.  
  1706.                             ScreenSizeStuff();
  1707.                         }
  1708.                     }
  1709.                     else
  1710.                     {
  1711.                         if(Config -> EmulationConfig -> FontScale != SCALE_NORMAL)
  1712.                         {
  1713.                             PrivateConfig = Config;
  1714.  
  1715.                             Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  1716.  
  1717.                             ScreenSizeStuff();
  1718.                         }
  1719.                     }
  1720.  
  1721.                     CursorX = CursorY = 0;
  1722.  
  1723.                     ClipBlitCursor(FALSE,TRUE);
  1724.  
  1725.                     EraseScreen("2");
  1726.  
  1727.                     break;
  1728.  
  1729.                     /* Set scroll mode (jump or smooth). */
  1730.  
  1731.                 case '4':
  1732.  
  1733.                     if(Buffer[3] == 'h')
  1734.                         Config -> EmulationConfig -> ScrollMode = SCROLL_SMOOTH;
  1735.                     else
  1736.                         Config -> EmulationConfig -> ScrollMode = SCROLL_JUMP;
  1737.  
  1738.                     break;
  1739.  
  1740.                     /* Turn region on or off. */
  1741.  
  1742.                 case '6':
  1743.  
  1744.                     if(Buffer[3] == 'h')
  1745.                         UseRegion = TRUE;
  1746.                     else
  1747.                         UseRegion = FALSE;
  1748.  
  1749.                     ResetCursor();
  1750.  
  1751.                     break;
  1752.  
  1753.                     /* Turn character wrapping on or off. */
  1754.  
  1755.                 case '7':
  1756.  
  1757.                     if(Buffer[3] == 'h')
  1758.                         Config -> EmulationConfig -> LineWrap = TRUE;
  1759.                     else
  1760.                         Config -> EmulationConfig -> LineWrap = FALSE;
  1761.  
  1762.                     break;
  1763.  
  1764.                     /* Set interlaced mode. */
  1765.  
  1766.                 case '9':
  1767.  
  1768.                     if(Buffer[3] == 'h')
  1769.                     {
  1770.                         if(!(Config -> ScreenConfig -> DisplayMode & LACE))
  1771.                         {
  1772.                             if(!ModeNotAvailable(Config -> ScreenConfig -> DisplayMode | LACE))
  1773.                             {
  1774.                                 SaveConfig(Config,PrivateConfig);
  1775.  
  1776.                                 Config -> ScreenConfig -> DisplayMode |= LACE;
  1777.  
  1778.                                 ResetDisplay = TRUE;
  1779.                             }
  1780.                         }
  1781.                     }
  1782.                     else
  1783.                     {
  1784.                         if(Config -> ScreenConfig -> DisplayMode & LACE)
  1785.                         {
  1786.                             if(!ModeNotAvailable(Config -> ScreenConfig -> DisplayMode & ~LACE))
  1787.                             {
  1788.                                 SaveConfig(Config,PrivateConfig);
  1789.  
  1790.                                 Config -> ScreenConfig -> DisplayMode &= ~LACE;
  1791.  
  1792.                                 ResetDisplay = TRUE;
  1793.                             }
  1794.                         }
  1795.                     }
  1796.  
  1797.                     break;
  1798.             }
  1799.  
  1800.             break;
  1801.  
  1802.         case '2':
  1803.  
  1804.                 /* Set newline mode. */
  1805.  
  1806.             if(Buffer[2] == '0')
  1807.             {
  1808.                 if(Buffer[3] == 'h')
  1809.                     Config -> EmulationConfig -> NewLineMode = TRUE;
  1810.                 else
  1811.                     Config -> EmulationConfig -> NewLineMode = FALSE;
  1812.             }
  1813.  
  1814.             break;
  1815.  
  1816.         case '4':
  1817.  
  1818.                 /* Set insert mode. */
  1819.  
  1820.             if(Buffer[2] == 'h')
  1821.                 Config -> EmulationConfig -> InsertMode = TRUE;
  1822.             else
  1823.                 Config -> EmulationConfig -> InsertMode = FALSE;
  1824.  
  1825.             break;
  1826.  
  1827.         case '1':
  1828.  
  1829.                 /* Print region or screen. */
  1830.  
  1831.             if(Buffer[2] == '9')
  1832.             {
  1833.                 if(Buffer[3] == 'l')
  1834.                 {
  1835.                     if(RegionSet)
  1836.                         PrintRegion(Top,Bottom + 1);
  1837.                     else
  1838.                         PrintRegion(0,LastLine + 1);
  1839.                 }
  1840.  
  1841.                 if(Buffer[3] == 'h')
  1842.                     PrintRegion(0,LastLine + 1);
  1843.             }
  1844.  
  1845.             break;
  1846.  
  1847.         default:
  1848.  
  1849.             break;
  1850.     }
  1851. }
  1852.  
  1853.     /* NumericAppMode(STRPTR Buffer):
  1854.      *
  1855.      *    Set the numeric pad applications mode.
  1856.      */
  1857.  
  1858. VOID __regargs
  1859. NumericAppMode(STRPTR Buffer)
  1860. {
  1861.     if(*Buffer == '=')
  1862.         Config -> EmulationConfig -> NumericMode = TRUE;
  1863.     else
  1864.     {
  1865.         if(*Buffer == '>')
  1866.             Config -> EmulationConfig -> NumericMode = FALSE;
  1867.     }
  1868. }
  1869.  
  1870.     /* MoveCursor(STRPTR Buffer):
  1871.      *
  1872.      *    Move the cursor in some direction and stop at
  1873.      *    top/bottom/margin if necessary.
  1874.      */
  1875.  
  1876. VOID __regargs
  1877. MoveCursor(STRPTR Buffer)
  1878. {
  1879.     WORD Value,Hit,LastCharPosition;
  1880.     BYTE InRegion = TRUE;
  1881.  
  1882.     ReadValue(Buffer,&Value);
  1883.  
  1884.     if(Value < 1)
  1885.         Value = 1;
  1886.  
  1887.     switch(LastChar(Buffer))
  1888.     {
  1889.             /* Move cursor Up value lines */
  1890.  
  1891.         case 'A':
  1892.  
  1893. ScrollUp:        Hit = 0;
  1894.  
  1895.             if(RegionSet)
  1896.             {
  1897.                 if(CursorY >= Top)
  1898.                     Hit = Top;
  1899.                 else
  1900.                     InRegion = FALSE;
  1901.             }
  1902.  
  1903.             CursorY -= Value;
  1904.  
  1905.             if(CursorY < Hit)
  1906.             {
  1907.                 Value = CursorY - Hit;
  1908.  
  1909.                 CursorY = Hit;
  1910.  
  1911.                 if(Config -> EmulationConfig -> CursorWrap && InRegion)
  1912.                     ScrollRegion(Value);
  1913.             }
  1914.  
  1915.             ConFontScaleUpdate();
  1916.  
  1917.             break;
  1918.  
  1919.             /* Move cursor Down value lines */
  1920.  
  1921.         case 'B':
  1922.  
  1923. ScrollDown:        Hit = LastLine;
  1924.  
  1925.             if(RegionSet)
  1926.             {
  1927.                 if(CursorY <= Bottom)
  1928.                     Hit = Bottom;
  1929.                 else
  1930.                     InRegion = FALSE;
  1931.             }
  1932.  
  1933.             CursorY += Value;
  1934.  
  1935.             if(CursorY > Hit)
  1936.             {
  1937.                 Value = CursorY - Hit;
  1938.  
  1939.                 CursorY = Hit;
  1940.  
  1941.                 if(Config -> EmulationConfig -> CursorWrap && InRegion)
  1942.                     ScrollRegion(Value);
  1943.             }
  1944.  
  1945.             ConFontScaleUpdate();
  1946.  
  1947.             break;
  1948.  
  1949.             /* Move cursor Right value columns */
  1950.  
  1951.         case 'C':
  1952.  
  1953.             CursorX += Value;
  1954.  
  1955.             if(CursorX > LastColumn)
  1956.             {
  1957.                 if(Config -> EmulationConfig -> CursorWrap)
  1958.                 {
  1959.                     Value     = CursorX / (LastColumn + 1);
  1960.  
  1961.                     CursorX    -= Value * (LastColumn + 1);
  1962.  
  1963.                     goto ScrollDown;
  1964.                 }
  1965.                 else
  1966.                     CursorX = LastColumn;
  1967.             }
  1968.  
  1969.             break;
  1970.  
  1971.             /* Move cursor Left value columns */
  1972.  
  1973.         case 'D':
  1974.  
  1975.             CursorX -= Value;
  1976.  
  1977.             if(CursorX < 0)
  1978.             {
  1979.                 if(Config -> EmulationConfig -> CursorWrap)
  1980.                 {
  1981.                     Value     = CursorX / (LastColumn + 1);
  1982.                     CursorX    -= Value * (LastColumn + 1);
  1983.                     Value     = -Value;
  1984.  
  1985.                     goto ScrollDown;
  1986.                 }
  1987.                 else
  1988.                     CursorX = 0;
  1989.             }
  1990.  
  1991.             break;
  1992.     }
  1993.  
  1994.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1995.         LastCharPosition = LastColumn;
  1996.     else
  1997.         LastCharPosition = ((LastColumn + 1) / 2) - 1;
  1998.  
  1999.     if(CursorX > LastCharPosition)
  2000.         CursorX = LastCharPosition;
  2001.  
  2002.     ClipBlitCursor(FALSE,TRUE);
  2003. }
  2004.  
  2005.     /* EraseLine(STRPTR Buffer):
  2006.      *
  2007.      *    Erase a line on the display.
  2008.      */
  2009.  
  2010. VOID __regargs
  2011. EraseLine(STRPTR Buffer)
  2012. {
  2013.     WORD Value,Width = GetFontWidth();
  2014.  
  2015.     ReadValue(Buffer,&Value);
  2016.  
  2017.     BackupRender();
  2018.  
  2019.     SetAPen(RPort,MappedPens[0][0]);
  2020.  
  2021.     switch(Value)
  2022.     {
  2023.         case 1:
  2024.  
  2025.             ScrollLineRectFill(RPort,0,MUL_Y(CursorY),((CursorX + 1) * Width) - 1,MUL_Y(CursorY + 1) - 1);
  2026.             break;
  2027.  
  2028.         case 2:
  2029.  
  2030.             ScrollLineRectFill(RPort,0,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2031.             break;
  2032.  
  2033.         default:
  2034.  
  2035.             ScrollLineRectFill(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2036.             break;
  2037.     }
  2038.  
  2039.     ScrollLineEraseLine(Value);
  2040.  
  2041.     RasterEraseLine(Value);
  2042.  
  2043.     BackupRender();
  2044. }
  2045.  
  2046.     /* EraseScreen(STRPTR Buffer):
  2047.      *
  2048.      *    Erase parts of the screen.
  2049.      */
  2050.  
  2051. VOID __regargs
  2052. EraseScreen(STRPTR Buffer)
  2053. {
  2054.     WORD Value,Width = GetFontWidth();
  2055.  
  2056.     ReadValue(Buffer,&Value);
  2057.  
  2058.     BackupRender();
  2059.  
  2060.     SetAPen(RPort,MappedPens[0][0]);
  2061.  
  2062.     switch(Value)
  2063.     {
  2064.         case 1:
  2065.  
  2066.             if(CursorY)
  2067.                 ScrollLineRectFill(RPort,0,0,LastPixel,MUL_Y(CursorY) - 1);
  2068.  
  2069.             ScrollLineRectFill(RPort,0,MUL_Y(TextFontHeight),((CursorX + 1) * Width) - 1,MUL_Y(CursorY + 1) - 1);
  2070.  
  2071.             break;
  2072.  
  2073.         case 2:
  2074.  
  2075.             ScrollLineRectFill(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2076.  
  2077.             if(Config -> EmulationConfig -> CLSResetsCursor)
  2078.                 CursorX = CursorY = 0;
  2079.  
  2080.             break;
  2081.  
  2082.         default:
  2083.  
  2084.             ScrollLineRectFill(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2085.  
  2086.             if(CursorY != LastLine)
  2087.                 ScrollLineRectFill(RPort,0,MUL_Y(CursorY + 1),LastPixel,MUL_Y(LastLine + 1) - 1);
  2088.  
  2089.             break;
  2090.     }
  2091.  
  2092.     ScrollLineEraseScreen(Value);
  2093.  
  2094.     RasterEraseScreen(Value);
  2095.  
  2096.     BackupRender();
  2097. }
  2098.  
  2099.     /* EraseCharacters(STRPTR Buffer):
  2100.      *
  2101.      *    Erase a number of characters.
  2102.      */
  2103.  
  2104. VOID __regargs
  2105. EraseCharacters(STRPTR Buffer)
  2106. {
  2107.     WORD Value,Width = GetFontWidth();
  2108.  
  2109.     ReadValue(Buffer,&Value);
  2110.  
  2111.     BackupRender();
  2112.  
  2113.     if(Value < 1)
  2114.         Value = 1;
  2115.  
  2116.     RasterEraseCharacters(Value);
  2117.  
  2118.     ScrollLineEraseCharacters(Value);
  2119.  
  2120.     ScrollLineRaster(RPort,Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2121.  
  2122.     BackupRender();
  2123. }
  2124.  
  2125.     /* InsertCharacters(STRPTR Buffer):
  2126.      *
  2127.      *    Insert a number of characters.
  2128.      */
  2129.  
  2130. VOID __regargs
  2131. InsertCharacters(STRPTR Buffer)
  2132. {
  2133.     WORD Value,Width = GetFontWidth();
  2134.  
  2135.     ReadValue(Buffer,&Value);
  2136.  
  2137.     BackupRender();
  2138.  
  2139.     if(Value < 1)
  2140.         Value = 1;
  2141.  
  2142.     RasterShiftChar(Value);
  2143.  
  2144.     ScrollLineShiftChar(Value);
  2145.  
  2146.     ScrollLineRaster(RPort,-Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2147.  
  2148.     BackupRender();
  2149. }
  2150.  
  2151.     /* InsertLine(STRPTR Buffer):
  2152.      *
  2153.      *    Insert a number of lines and scroll the rest of the
  2154.      *    display down.
  2155.      */
  2156.  
  2157. VOID __regargs
  2158. InsertLine(STRPTR Buffer)
  2159. {
  2160.     WORD Value,RegionBottom,RegionTop,TheTop = CursorY;
  2161.  
  2162.     ReadValue(Buffer,&Value);
  2163.  
  2164.     BackupRender();
  2165.  
  2166.     SetAPen(RPort,MappedPens[0][0]);
  2167.  
  2168.     if(Value < 1)
  2169.         Value = 1;
  2170.  
  2171.     if(RegionSet)
  2172.     {
  2173.         RegionTop    = Top;
  2174.         RegionBottom    = Bottom + 1;
  2175.     }
  2176.     else
  2177.     {
  2178.         RegionTop    = 0;
  2179.         RegionBottom    = LastLine + 1;
  2180.     }
  2181.  
  2182.     if(TheTop < RegionTop)
  2183.         TheTop = RegionTop;
  2184.  
  2185.     RasterInsertLine(Value,TheTop);
  2186.  
  2187.     ScrollLineRaster(RPort,0,-MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2188.  
  2189.     BackupRender();
  2190. }
  2191.  
  2192.     /* ClearLine(STRPTR Buffer):
  2193.      *
  2194.      *    Clear a number of lines and scroll up the ones below it.
  2195.      */
  2196.  
  2197. VOID __regargs
  2198. ClearLine(STRPTR Buffer)
  2199. {
  2200.     WORD Value,RegionBottom,RegionTop,TheTop = CursorY;
  2201.  
  2202.     ReadValue(Buffer,&Value);
  2203.  
  2204.     BackupRender();
  2205.  
  2206.     SetAPen(RPort,MappedPens[0][0]);
  2207.  
  2208.     if(Value < 1)
  2209.         Value = 1;
  2210.  
  2211.     if(RegionSet)
  2212.     {
  2213.         RegionTop    = Top;
  2214.         RegionBottom    = Bottom + 1;
  2215.     }
  2216.     else
  2217.     {
  2218.         RegionTop    = 0;
  2219.         RegionBottom    = LastLine + 1;
  2220.     }
  2221.  
  2222.     if(TheTop < RegionTop)
  2223.         TheTop = RegionTop;
  2224.  
  2225.     RasterClearLine(Value,TheTop);
  2226.  
  2227.     ScrollLineRaster(RPort,0,MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2228.  
  2229.     BackupRender();
  2230. }
  2231.  
  2232.     /* SetTabs(STRPTR Buffer):
  2233.      *
  2234.      *    Set the current tab stops.
  2235.      */
  2236.  
  2237. VOID __regargs
  2238. SetTabs(STRPTR Buffer)
  2239. {
  2240.     WORD Value;
  2241.  
  2242.     ReadValue(Buffer,&Value);
  2243.  
  2244.     if(Value < 1)
  2245.         Value = 0;
  2246.  
  2247.     switch(Value)
  2248.     {
  2249.         case 0:
  2250.  
  2251.             if(CursorX < TabStopMax)
  2252.                 TabStops[CursorX] = FALSE;
  2253.  
  2254.             break;
  2255.  
  2256.         case 3:
  2257.  
  2258.             memset(TabStops,FALSE,TabStopMax);
  2259.  
  2260.             break;
  2261.  
  2262.         default:
  2263.  
  2264.             break;
  2265.     }
  2266. }
  2267.  
  2268.     /* SetAbsolutePosition(STRPTR Buffer):
  2269.      *
  2270.      *    Move the cursor to a given location on the display,
  2271.      *    this routine ignores the current scroll region
  2272.      *    settings.
  2273.      */
  2274.  
  2275. VOID __regargs
  2276. SetAbsolutePosition(STRPTR Buffer)
  2277. {
  2278.     WORD Value;
  2279.  
  2280.     Buffer = ReadValue(Buffer,&Value);
  2281.  
  2282.     if(UseRegion && RegionSet)
  2283.         CursorY = Top;
  2284.     else
  2285.         CursorY = 0;
  2286.  
  2287.     CursorX = 0;
  2288.  
  2289.     if(Value != -1)
  2290.     {
  2291.             /* Our raster origin is 0/0 instead of 1/1. */
  2292.  
  2293.         if(Value)
  2294.             Value--;
  2295.  
  2296.         if(UseRegion && RegionSet)
  2297.             CursorY = Top + Value;
  2298.         else
  2299.             CursorY = Value;
  2300.  
  2301.         if(Buffer)
  2302.         {
  2303.             ReadValue(Buffer,&Value);
  2304.  
  2305.             if(Value > 0)
  2306.                 CursorX = Value - 1;
  2307.             else
  2308.                 CursorX = 0;
  2309.         }
  2310.  
  2311.             /* Truncate illegal positions. */
  2312.  
  2313.         if(CursorX > LastColumn)
  2314.             CursorX = LastColumn;
  2315.  
  2316.         if(CursorY > LastLine)
  2317.             CursorY = LastLine;
  2318.     }
  2319.  
  2320.     ConFontScaleUpdate();
  2321.  
  2322.     ClipBlitCursor(FALSE,TRUE);
  2323. }
  2324.  
  2325.     /* SetAttributes(STRPTR Buffer):
  2326.      *
  2327.      *    Set the current display rendering attributes.
  2328.      */
  2329.  
  2330. VOID __regargs
  2331. SetAttributes(STRPTR Buffer)
  2332. {
  2333.     LONG TextFlags = FS_NORMAL;
  2334.     WORD Value;
  2335.  
  2336.     do
  2337.     {
  2338.         Buffer = ReadValue(Buffer,&Value);
  2339.  
  2340.         if(Value == -1)
  2341.             Value = 0;
  2342.  
  2343.         switch(Value)
  2344.         {
  2345.             case 0:
  2346.  
  2347.                 FgPen = GetPenIndex(SafeTextPen);
  2348.                 BgPen = 0;
  2349.  
  2350.                 Attributes = 0;
  2351.  
  2352.                 break;
  2353.  
  2354.             case 1:
  2355.  
  2356.                 Attributes |= ATTR_HIGHLIGHT;
  2357.  
  2358.                 break;
  2359.  
  2360.             case 4:
  2361.  
  2362.                 Attributes |= ATTR_UNDERLINE;
  2363.  
  2364.                 break;
  2365.  
  2366.             case 5:
  2367.  
  2368.                 Attributes |= ATTR_BLINK;
  2369.  
  2370.                 break;
  2371.  
  2372.             case 7:
  2373.  
  2374.                 if(!(Attributes & ATTR_INVERSE))
  2375.                 {
  2376.                     BYTE Help;
  2377.  
  2378.                     Help    = FgPen;
  2379.                     FgPen    = BgPen;
  2380.                     BgPen    = Help;
  2381.                 }
  2382.  
  2383.                 Attributes |= ATTR_INVERSE;
  2384.  
  2385.                 break;
  2386.  
  2387.             default:
  2388.  
  2389.                 if(Value >= 30)
  2390.                 {
  2391.                     if(Value <= 37)
  2392.                     {
  2393.                         if(Attributes & ATTR_INVERSE)
  2394.                             BgPen = Value - 30;
  2395.                         else
  2396.                             FgPen = Value - 30;
  2397.                     }
  2398.                     else
  2399.                     {
  2400.                         if(Value >= 40 && Value <= 47)
  2401.                         {
  2402.                             if(Attributes & ATTR_INVERSE)
  2403.                                 FgPen = Value - 40;
  2404.                             else
  2405.                                 BgPen = Value - 40;
  2406.                         }
  2407.                     }
  2408.                 }
  2409.  
  2410.                 break;
  2411.         }
  2412.     }
  2413.     while(Buffer);
  2414.  
  2415.         /* Make sure that the text rendered will be
  2416.          * visible by wrapping the colour if
  2417.          * necessary.
  2418.          */
  2419.  
  2420.     if(FgPen > DepthMask && !(FgPen & DepthMask))
  2421.         FgPen = GetPenIndex(SafeTextPen);
  2422.  
  2423.     if(BgPen > DepthMask && !(BgPen & DepthMask))
  2424.         BgPen = GetPenIndex(SafeTextPen);
  2425.  
  2426.     if(Attributes & ATTR_UNDERLINE)
  2427.         TextFlags |= FSF_UNDERLINED;
  2428.  
  2429.     if(Attributes & ATTR_HIGHLIGHT)
  2430.     {
  2431.         if(Config -> ScreenConfig -> ColourMode == COLOUR_SIXTEEN)
  2432.         {
  2433.             if(Attributes & ATTR_INVERSE)
  2434.                 BgPen |= 8;
  2435.             else
  2436.                 FgPen |= 8;
  2437.         }
  2438.         else
  2439.             TextFlags |= FSF_BOLD;
  2440.     }
  2441.  
  2442.     if(Attributes & ATTR_BLINK)
  2443.     {
  2444.         if(Config -> TerminalConfig -> EmulationMode == EMULATION_ANSIVT100)
  2445.         {
  2446.             switch(Config -> ScreenConfig -> ColourMode)
  2447.             {
  2448.                 case COLOUR_AMIGA:
  2449.  
  2450.                     if(Attributes & ATTR_INVERSE)
  2451.                         BgPen = 3;
  2452.                     else
  2453.                         FgPen = 3;
  2454.  
  2455.                     break;
  2456.  
  2457.                 case COLOUR_EIGHT:
  2458.  
  2459.                     if(Attributes & ATTR_INVERSE)
  2460.                         BgPen |= 8;
  2461.                     else
  2462.                         FgPen |= 8;
  2463.  
  2464.                     break;
  2465.  
  2466.                 case COLOUR_SIXTEEN:
  2467.  
  2468.                     if(Screen)
  2469.                     {
  2470.                         if(Screen -> RastPort . BitMap -> Depth > 4)
  2471.                         {
  2472.                             if(Attributes & ATTR_INVERSE)
  2473.                                 BgPen |= 16;
  2474.                             else
  2475.                                 FgPen |= 16;
  2476.                         }
  2477.                     }
  2478.  
  2479.                     break;
  2480.  
  2481.                 case COLOUR_MONO:
  2482.  
  2483.                     if(Attributes & ATTR_INVERSE)
  2484.                         BgPen = GetPenIndex(SafeTextPen);
  2485.                     else
  2486.                         FgPen = GetPenIndex(SafeTextPen);
  2487.  
  2488.                     break;
  2489.             }
  2490.         }
  2491.     }
  2492.  
  2493.     if(TextFlags != StyleType)
  2494.     {
  2495.         SetSoftStyle(RPort,TextFlags,0xFF);
  2496.  
  2497.         StyleType = TextFlags;
  2498.     }
  2499.  
  2500.     if(Config -> ScreenConfig -> ColourMode == COLOUR_MONO)
  2501.     {
  2502.         if(ColourValue(MappedPens[0][FgPen]) < ColourValue(MappedPens[0][BgPen]))
  2503.         {
  2504.             if(Attributes & ATTR_INVERSE)
  2505.             {
  2506.                 FgPen = GetPenIndex(SafeTextPen);
  2507.                 BgPen = 0;
  2508.             }
  2509.             else
  2510.             {
  2511.                 FgPen = 0;
  2512.                 BgPen = GetPenIndex(SafeTextPen);
  2513.             }
  2514.         }
  2515.         else
  2516.         {
  2517.             if(Attributes & ATTR_INVERSE)
  2518.             {
  2519.                 FgPen = 0;
  2520.                 BgPen = GetPenIndex(SafeTextPen);
  2521.             }
  2522.             else
  2523.             {
  2524.                 FgPen = GetPenIndex(SafeTextPen);
  2525.                 BgPen = 0;
  2526.             }
  2527.         }
  2528.     }
  2529.  
  2530.     if(MappedPens[0][FgPen] != ReadAPen(RPort))
  2531.         SetAPen(RPort,MappedPens[0][FgPen]);
  2532.  
  2533.     if(MappedPens[0][BgPen] != ReadBPen(RPort))
  2534.         SetBPen(RPort,MappedPens[0][BgPen]);
  2535.  
  2536.     ClipBlitCursor(FALSE,TRUE);
  2537. }
  2538.  
  2539.     /* SetRegion(STRPTR Buffer):
  2540.      *
  2541.      *    Set the current scroll region top and bottom.
  2542.      */
  2543.  
  2544. VOID __regargs
  2545. SetRegion(STRPTR Buffer)
  2546. {
  2547.     WORD NewTop,Value,NewBottom = LastLine;
  2548.  
  2549.     Buffer = ReadValue(Buffer,&Value);
  2550.  
  2551.     if(!Value)
  2552.         Value = 1;
  2553.  
  2554.     if(Value > 0)
  2555.     {
  2556.         if(Buffer)
  2557.         {
  2558.             NewTop = Value - 1;
  2559.  
  2560.             ReadValue(Buffer,&Value);
  2561.  
  2562.             if(Value > 0)
  2563.                 NewBottom = Value - 1;
  2564.  
  2565.             if(NewBottom > LastLine)
  2566.                 NewBottom = LastLine;
  2567.  
  2568.             if(NewTop > LastLine)
  2569.                 NewTop = LastLine;
  2570.         }
  2571.         else
  2572.         {
  2573.             NewTop        = 0;
  2574.             NewBottom    = LastLine;
  2575.         }
  2576.     }
  2577.     else
  2578.     {
  2579.         NewTop        = 0;
  2580.         NewBottom    = LastLine;
  2581.     }
  2582.  
  2583.     if(NewTop < NewBottom)
  2584.     {
  2585.         if(NewTop != 0 || NewBottom != LastLine)
  2586.         {
  2587.             Top    = NewTop;
  2588.             Bottom    = NewBottom;
  2589.  
  2590.             RegionSet = TRUE;
  2591.         }
  2592.         else
  2593.             UseRegion = RegionSet = FALSE;
  2594.  
  2595.         ResetCursor();
  2596.     }
  2597.     else
  2598.         RegionSet = FALSE;
  2599. }
  2600.  
  2601.     /* ResetCursor():
  2602.      *
  2603.      *    Reset cursor to top of screen.
  2604.      */
  2605.  
  2606. VOID
  2607. ResetCursor()
  2608. {
  2609.     CursorX    = 0;
  2610.  
  2611.     if(UseRegion && RegionSet)
  2612.         CursorY = Top;
  2613.     else
  2614.         CursorY    = 0;
  2615.  
  2616.     ConFontScaleUpdate();
  2617.  
  2618.     ClipBlitCursor(FALSE,TRUE);
  2619. }
  2620.